{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 完成对20类新闻数据集，通过贝叶斯分析，实现分类预测，理解贝叶斯公式计算方法，",
   "id": "17238b9a9e03edd0"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-02T00:51:41.340630Z",
     "start_time": "2025-03-02T00:51:40.698929Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.datasets import fetch_20newsgroups\n",
    "from sklearn.model_selection import train_test_split  # 划分数据集\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer  # 特征抽取，TF-IDF 针对非连续数据，对文本进行向量化，特征化\n",
    "from sklearn.naive_bayes import MultinomialNB  # 朴素贝叶斯模型\n",
    "from sklearn.metrics import accuracy_score, classification_report  # 准确率计算\n",
    "from sklearn.metrics import roc_auc_score    # 计算AUC值"
   ],
   "id": "f3e76dcefacb6b19",
   "outputs": [],
   "execution_count": 1
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 数据预处理",
   "id": "23aaafa48058a0e4"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "加载数据集",
   "id": "f54da610d986265f"
  },
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-03-02T00:51:41.503357Z",
     "start_time": "2025-03-02T00:51:41.340630Z"
    }
   },
   "source": [
    "news = fetch_20newsgroups(subset='all', data_home='.')\n",
    "print('-' * 50)\n",
    "print(type(news.data))  # 打印数据类型\n",
    "print(news.data[0])  # 打印第一条数据\n",
    "print('-' * 50)\n",
    "print(news.target)  # 打印目标值\n",
    "print(np.unique(news.target))  # 打印目标值唯一值\n",
    "print(type(news.target_names))  # 打印目标名称\n",
    "print(len(news.target))\n",
    "print(len(np.unique(news.target)))  # 20个类别\n",
    "print('-' * 50)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--------------------------------------------------\n",
      "<class 'list'>\n",
      "From: Mamatha Devineni Ratnam <mr47+@andrew.cmu.edu>\n",
      "Subject: Pens fans reactions\n",
      "Organization: Post Office, Carnegie Mellon, Pittsburgh, PA\n",
      "Lines: 12\n",
      "NNTP-Posting-Host: po4.andrew.cmu.edu\n",
      "\n",
      "\n",
      "\n",
      "I am sure some bashers of Pens fans are pretty confused about the lack\n",
      "of any kind of posts about the recent Pens massacre of the Devils. Actually,\n",
      "I am  bit puzzled too and a bit relieved. However, I am going to put an end\n",
      "to non-PIttsburghers' relief with a bit of praise for the Pens. Man, they\n",
      "are killing those Devils worse than I thought. Jagr just showed you why\n",
      "he is much better than his regular season stats. He is also a lot\n",
      "fo fun to watch in the playoffs. Bowman should let JAgr have a lot of\n",
      "fun in the next couple of games since the Pens are going to beat the pulp out of Jersey anyway. I was very disappointed not to see the Islanders lose the final\n",
      "regular season game.          PENS RULE!!!\n",
      "\n",
      "\n",
      "--------------------------------------------------\n",
      "[10  3 17 ...  3  1  7]\n",
      "[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]\n",
      "<class 'list'>\n",
      "18846\n",
      "20\n",
      "--------------------------------------------------\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "划分数据集",
   "id": "5a48bb3f10fc751e"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-02T00:51:41.508752Z",
     "start_time": "2025-03-02T00:51:41.503357Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 划分数据集 \n",
    "x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.25, random_state=1)"
   ],
   "id": "3f78851cd35ae90f",
   "outputs": [],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 特征工程",
   "id": "1a79562aaf0471fd"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-02T00:51:43.183946Z",
     "start_time": "2025-03-02T00:51:41.508752Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 因为数据是文本类型，需要进行特征工程，特征抽取，所以可以用TF-IDF进行特征向量化\n",
    "# Tf:term frequency:词的频率出现的次数\n",
    "# idf:逆文档频率inverse document frequency    log(总文档数量/该词出现的文档数量)  以10为低\n",
    "# tf*idf  来代表重要性程度:\n",
    "tfidf = TfidfVectorizer()  # 文本特征向量化 TF-IDF:词频-逆文档频率 实例化TfIdfVectorizer\n",
    "x_train = tfidf.fit_transform(x_train)  # 训练集特征向量化"
   ],
   "id": "d805bf542204b82a",
   "outputs": [],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-02T00:51:43.362186Z",
     "start_time": "2025-03-02T00:51:43.184950Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(len(tfidf.get_feature_names_out()))  # 打印特征数量\n",
    "print(type(x_train))  # 打印特征向量类型\n",
    "print(x_train.shape)  # 打印特征向量维度\n",
    "print(tfidf.get_feature_names_out()[0:100])  # 打印前100个特征名称\n",
    "print('-' * 50)\n",
    "print(tfidf.get_feature_names_out()[-100:])  # 打印后100个特征名称"
   ],
   "id": "28eb58872c309823",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "153196\n",
      "<class 'scipy.sparse._csr.csr_matrix'>\n",
      "(14134, 153196)\n",
      "['00' '000' '0000' '00000' '0000000004' '0000000005' '0000000667'\n",
      " '0000001200' '000003' '000005102000' '00000510200001' '000007' '00000f'\n",
      " '000020' '000021' '000042' '000050' '000062david42' '000094' '0000ahc'\n",
      " '0000vec' '0001' '000100255pixel' '00014' '000152' '0001mpc' '0001x7c'\n",
      " '0002' '000246' '000256' '0003' '000337' '000359' '0004' '000406'\n",
      " '000410' '00041032' '000413' '0004136' '00041555' '0004244402' '00043819'\n",
      " '0004422' '0004847546' '0004988' '0005' '0005111312' '0005111312na1em'\n",
      " '000531' '0005895485' '0006' '000601' '0007' '000710' '00072' '000758'\n",
      " '0007sxc' '00081100' '000821' '000851' '0008512' '0009' '00090711'\n",
      " '000bps' '000ds' '000hz' '000iu' '000k' '000mg' '000mi' '000miles'\n",
      " '000puq9' '000rpm' '000s' '000th' '000ug' '000usd' '001' '0010'\n",
      " '00100111b' '001004' '0010580b' '0011' '001102' '001116' '001125'\n",
      " '001127' '0012' '001200201pixel' '001211' '001230' '0013' '001319'\n",
      " '001321' '001323' '001326' '001338' '0014' '00140' '001428']\n",
      "--------------------------------------------------\n",
      "['zxw' 'zxw8' 'zxxsm' 'zxxst' 'zxyiss' 'zxyx' 'zxz' 'zy' 'zy1' 'zy15'\n",
      " 'zy2m' 'zy2mqr' 'zy3' 'zy4uj' 'zy5' 'zy68a' 'zy7' 'zy8' 'zy84' 'zy_63'\n",
      " 'zya7' 'zya7hp' 'zyc' 'zycg' 'zyckp' 'zyda' 'zydc' 'zydjepqzl2' 'zye'\n",
      " 'zyeh' 'zygon' 'zygt' 'zyj' 'zyjb6' 'zyklon' 'zylorq' 'zym' 'zymq2th_s'\n",
      " 'zyr' 'zyr01' 'zyra' 'zysec' 'zysgm3r' 'zysv' 'zyt' 'zyu' 'zyv' 'zyw1n'\n",
      " 'zyxel' 'zyxel1496b' 'zz' 'zz0' 'zz20d' 'zz2q1' 'zz3' 'zz5co'\n",
      " 'zz93sigmc120' 'zz96w' 'zz9s' 'zzc6' 'zzcrm' 'zzd' 'zzf' 'zzg6c' 'zzi776'\n",
      " 'zzneu' 'zznki' 'zznkj' 'zznkjz' 'zznkzz' 'zznp' 'zzo' 'zzq' 'zzr1100'\n",
      " 'zzrk' 'zzs' 'zzt' 'zztop' 'zzvsi' 'zzx' 'zzy_3w' 'zzzoh' 'zzzz' 'zzzzzz'\n",
      " 'zzzzzzt' 'ªl' '³ation'\n",
      " 'º_________________________________________________º_____________________º'\n",
      " 'ºnd' 'çait' 'çon' 'ère' 'ée' 'égligent' 'élangea' 'érale' 'ête'\n",
      " 'ñaustin' 'ýé' 'ÿhooked']\n"
     ]
    }
   ],
   "execution_count": 5
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 机器学习模型选择和训练",
   "id": "2135b7a891ea7f5f"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "朴素贝叶斯",
   "id": "4cbbdbc8bd5f858d"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-02T00:51:43.927755Z",
     "start_time": "2025-03-02T00:51:43.362696Z"
    }
   },
   "cell_type": "code",
   "source": [
    "mlt = MultinomialNB(alpha=1.0)  # 实例化朴素贝叶斯模型 alpha参数控制平滑系数：拉普拉斯平滑，alpha越小，平滑程度越高\n",
    "mlt.fit(x_train, y_train)  # 训练模型\n",
    "x_test = tfidf.transform(x_test)  # 测试集特征向量化\n",
    "y_pred = mlt.predict(x_test)  # 预测结果"
   ],
   "id": "3bbf244e2902aa3f",
   "outputs": [],
   "execution_count": 6
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-02T00:51:43.931056Z",
     "start_time": "2025-03-02T00:51:43.927755Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(type(y_pred))  #    打印预测结果类型\n",
    "print(y_pred.shape)  #  打印预测结果维度，一共有4712条数据，每个数据预测结果是一个类别\n",
    "print(np.unique(y_pred))  # 打印预测结果唯一值"
   ],
   "id": "49d578854b73c2c7",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n",
      "(4712,)\n",
      "[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]\n"
     ]
    }
   ],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 模型评估",
   "id": "a13d759fceb15679"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "准确率",
   "id": "fbdd1788061579d6"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-02T00:51:43.941519Z",
     "start_time": "2025-03-02T00:51:43.931056Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# classification_report  打印准确率,召回率,F1-score和样本数.三个参数分别是真实值，预测值，类别名称\n",
    "print(f\"每个类别的精确率和召回率：{classification_report(y_test, y_pred, target_names=news.target_names)}\", )"
   ],
   "id": "f9613c7540e715a",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "每个类别的精确率和召回率：                          precision    recall  f1-score   support\n",
      "\n",
      "             alt.atheism       0.91      0.77      0.83       199\n",
      "           comp.graphics       0.83      0.79      0.81       242\n",
      " comp.os.ms-windows.misc       0.89      0.83      0.86       263\n",
      "comp.sys.ibm.pc.hardware       0.80      0.83      0.81       262\n",
      "   comp.sys.mac.hardware       0.90      0.88      0.89       234\n",
      "          comp.windows.x       0.92      0.85      0.88       230\n",
      "            misc.forsale       0.96      0.67      0.79       257\n",
      "               rec.autos       0.90      0.87      0.88       265\n",
      "         rec.motorcycles       0.90      0.95      0.92       251\n",
      "      rec.sport.baseball       0.89      0.96      0.93       226\n",
      "        rec.sport.hockey       0.95      0.98      0.96       262\n",
      "               sci.crypt       0.76      0.97      0.85       257\n",
      "         sci.electronics       0.84      0.80      0.82       229\n",
      "                 sci.med       0.97      0.86      0.91       249\n",
      "               sci.space       0.92      0.96      0.94       256\n",
      "  soc.religion.christian       0.55      0.98      0.70       243\n",
      "      talk.politics.guns       0.76      0.96      0.85       234\n",
      "   talk.politics.mideast       0.93      0.99      0.96       224\n",
      "      talk.politics.misc       0.98      0.56      0.72       197\n",
      "      talk.religion.misc       0.97      0.26      0.41       132\n",
      "\n",
      "                accuracy                           0.85      4712\n",
      "               macro avg       0.88      0.84      0.84      4712\n",
      "            weighted avg       0.87      0.85      0.85      4712\n",
      "\n"
     ]
    }
   ],
   "execution_count": 8
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "计算特征名为0的混淆矩阵，TP,FP,TN,FN,FPR,TPR,AUC",
   "id": "9335b073d47297ed"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-02T00:51:43.948044Z",
     "start_time": "2025-03-02T00:51:43.941519Z"
    }
   },
   "cell_type": "code",
   "source": [
    "y_test1 = np.where(y_test == 5, 1, 0)   # 将y_test中类别0替换为1,类别不为0替换为0\n",
    "y_pred1 = np.where(y_pred == 5, 1, 0)   # 将y_pred中类别0替换为1,类别不为0替换为0\n",
    "print(y_test1[0:100])     # 打印前100个真实值\n",
    "print(y_pred1[0:100])     # 打印前100个预测值\n",
    "print('-' * 50)\n",
    "print(f\"TP:True Positive={np.sum((y_test1 == 1) & (y_pred1 == 1))}\")\n",
    "print(f\"FP:False Positive={np.sum((y_test1 == 0) & (y_pred1 == 1))}\")\n",
    "print(f\"TN:True Negative={np.sum((y_test1 == 0) & (y_pred1 == 0))}\")\n",
    "print(f\"FN:False Negative={np.sum((y_test1 == 1) & (y_pred1 == 0))}\")\n",
    "print('-' * 50)\n",
    "# FPR: TP/(FP+TN)  FPR越小，模型的预测能力越强\n",
    "print(f\"FPR:False Positive Rate={np.sum((y_test1 == 0) & (y_pred1 == 1)) / np.sum(y_test1 == 0)}\")  # 计算FPR\n",
    "# TPR: TP/(TP+FN)  TPR越大，模型的召回能力越强\n",
    "print(f\"TPR:True Positive Rate={np.sum((y_test1 == 1) & (y_pred1 == 1)) / np.sum(y_test1 == 1)}\")   # 计算TPR\n",
    "print('-' * 50)\n",
    "print(f\"AUC:Area Under the Curve={roc_auc_score(y_test1, y_pred1)}\")    # roc_auc_score计算AUC值"
   ],
   "id": "5f53f3d74b81870",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0\n",
      " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0\n",
      " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]\n",
      "[0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0\n",
      " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0\n",
      " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]\n",
      "--------------------------------------------------\n",
      "TP:True Positive=196\n",
      "FP:False Positive=18\n",
      "TN:True Negative=4464\n",
      "FN:False Negative=34\n",
      "--------------------------------------------------\n",
      "FPR:False Positive Rate=0.004016064257028112\n",
      "TPR:True Positive Rate=0.8521739130434782\n",
      "--------------------------------------------------\n",
      "AUC:Area Under the Curve=0.924078924393225\n"
     ]
    }
   ],
   "execution_count": 9
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
